package de.koller.oceanFramework.gl.util;

import de.koller.oceanFramework.math.Vec3;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class ViewUtil {
	
	public static void readPixels( ParticleTexture out ) {
		readPixels( out, GL11.GL_RGBA );
	}
	
//	public static void readDepth( ParticleTexture out ) {
//		readPixelsF( out, GL11.GL_DEPTH_COMPONENT );
//	}
	
//	public static void readPixelsF( ParticleTexture out, int type ) {
//		GL11.glReadBuffer( GL11.GL_FRONT );
//		int w = out.getSize(), h = out.getSize();
//		FloatBuffer b = BufferUtils.createFloatBuffer( w*h );
//		GL11.glReadPixels( 0, 0, w, h, type, GL11.GL_FLOAT, b );
//		
//		for( int i = 0; i < w*h; i++ ) {
//			byte[] t = Bytnig.floatToByte( b.get( i ) );
//			out.getData()[i*4] = t[0];
//			out.getData()[i*4+1] = t[1];
//			out.getData()[i*4+2] = t[2];
//			out.getData()[i*4+3] = t[3];
//		}
//		
//		out.flush();
//	}
	
	public static void readPixels( ParticleTexture out, int type ) {
		GL11.glReadBuffer( GL11.GL_FRONT );
		int w = out.getWidth(), h = out.getHeight();
		ByteBuffer b = BufferUtils.createByteBuffer( w*h*4 );
		GL11.glReadPixels( 0, 0, w, h, type, GL11.GL_UNSIGNED_BYTE, b );
		
		for( int i = 0; i < w*h*4; i++ )
			out.getData()[i] = b.get( i );
		
		out.flipHorizontal();
		out.flush();
	}
	
	public static void initOrtho( int w, int h ) {
		GL11.glMatrixMode( GL11.GL_PROJECTION );
		GL11.glLoadIdentity();

		GL11.glOrtho( 0, w, h, 0, -1000, 1000 );
		
		GL11.glMatrixMode( GL11.GL_MODELVIEW );
		GL11.glLoadIdentity();
	}
	
	public static void initOrtho() {
		initOrtho( Display.getWidth(), Display.getHeight() );
	}
	
	public static void initPerspective() {
		GL11.glMatrixMode( GL11.GL_PROJECTION );
		GL11.glLoadIdentity();

		GLU.gluPerspective( 45.0f, (float)Display.getWidth()/(float)Display.getHeight(), 0.001f, 2000.0f );
	
		GL11.glMatrixMode( GL11.GL_MODELVIEW );
		GL11.glLoadIdentity();
	}

	public static void draw2D( float x, float y, float w, float h, float z ) {
		draw2D( x, y, w, h, z, 0, 0, 1, 1 );	
	}
	
	public static void draw2D( float x, float y, float w, float h, float z, float u0, float v0, float u1, float v1 ) {
		GL11.glBegin( GL11.GL_QUADS );
			GL11.glTexCoord2f( u0, v0 );
			GL11.glVertex3f( x, y, z );
			
			GL11.glTexCoord2f( u0, v1 );
			GL11.glVertex3f( x, y+h, z );
			
			GL11.glTexCoord2f( u1, v1 );
			GL11.glVertex3f( x+w, y+h, z );
			
			GL11.glTexCoord2f( u1, v0 );
			GL11.glVertex3f( x+w, y, z );
		GL11.glEnd();
	}
	
	public static void draw2D( int texture, float x, float y, float w, float h, float z, float u0, float v0, float u1, float v1 ) {
		TextureUtil.bind( texture );
		draw2D( x, y, w, h, z, u0, v0, u1, v1 );
	}
	
	public static Vec3 worldPosition( int x, int y, float z ) {
		IntBuffer viewport = BufferUtils.createIntBuffer( 16 );
		FloatBuffer modelview = BufferUtils.createFloatBuffer( 16 );
		FloatBuffer projection = BufferUtils.createFloatBuffer( 16 );
//		FloatBuffer winZ = BufferUtils.createFloatBuffer( 1 );
		float winX, winY;
		FloatBuffer pos = BufferUtils.createFloatBuffer( 3 );
		
		GL11.glGetFloat( GL11.GL_MODELVIEW_MATRIX, modelview );
		GL11.glGetFloat( GL11.GL_PROJECTION_MATRIX, projection );
		GL11.glGetInteger( GL11.GL_VIEWPORT, viewport );
		
		winX = (float)x;
		winY = (float)viewport.get( 3 ) - (float)y;
//		GL11.glReadPixels( x, (int)winY, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, winZ );
		
		//System.out.println( winZ.get() );
		GLU.gluUnProject( winX, winY, /*winZ.get()*/ z, modelview, projection, viewport, pos );
		return new Vec3( pos.get( 0 ), pos.get( 1 ), pos.get( 2 ) );
	}
	
}
